//
//  IMStockTools.m
//  Stock_Pro
//
//  Created by imuse on 10-11-26.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#include "IMStockTools.h"
#include "arpa/inet.h"

#define DEFAULT_SEND_BUF_SIZE 4096

IMSOCKET_TOOLS* ImSocketTools_New(char *ip, int port, void(*pCallBack)(IMSOCKET_TOOLS *pSocket, int nType), void *pCBObj)
{
	IMSOCKET_TOOLS* pSocket = Tools_Malloc(sizeof(IMSOCKET_TOOLS));
	
	strcpy(pSocket->sIP, ip);
	pSocket->nPort = port;
	
	pSocket->pCallBack = pCallBack;
	pSocket->pCBObj = pCBObj;
	
	//申请发送缓冲区
	pSocket->nSize = DEFAULT_SEND_BUF_SIZE;
	pSocket->pBuf = Tools_Malloc(pSocket->nSize);
	pSocket->nLen = 0;
	
	//创建连接
	pSocket->bStop = FALSE;
	pthread_create(&(pSocket->pConner), NULL, ImSocketTools_Conning, pSocket);
	
	return pSocket;
}


TBOOL isIP(char *pHost)
{
	char *p = pHost;
	while ((*p>=0x30 && *p<=0x39) || *p=='.')
	{
		p++;
	}
	return *p==0x00;
}

void* ImSocketTools_Conning(void *lpParam)
{
	IMSOCKET_TOOLS *pSocket;
	pSocket = ( IMSOCKET_TOOLS* )lpParam;
 	
	
	
	//创建套接字
	pSocket->iSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	struct hostent* host;
	
	pSocket->iSocketAddr.sin_family = AF_INET;
	
	//cmnet
	if (isIP(pSocket->sIP))
	{
		pSocket->iSocketAddr.sin_addr.s_addr = inet_addr(pSocket->sIP);
	}
	else
	{
		host = gethostbyname(pSocket->sIP);
		if (!host)
		{
			//HttpTools_NetError(pHttp);
			//失败处理
			goto EXIT;
		}
		pSocket->iSocketAddr.sin_addr = *((struct in_addr *)host->h_addr);
	}
	pSocket->iSocketAddr.sin_port = htons(pSocket->nPort);
	
	//建立和服务器的连接
	pSocket->iSocketAddr.sin_port = htons(pSocket->nPort);
	int iRet = connect(pSocket->iSocket, (struct sockaddr*) &pSocket->iSocketAddr, sizeof(pSocket->iSocketAddr));
	if (iRet==SOCKET_ERROR)
	{
		printf("\n conn error:%d", iRet);
		goto EXIT;
	}
	
	
	//连接成功,启动发送和接收线程
	pthread_create(&pSocket->pSender, NULL, ImSocketTools_Sending, pSocket);
	pthread_create(&pSocket->pReader, NULL, ImSocketTools_Reading, pSocket);
EXIT:
	
	return NULL;
}

void* ImSocketTools_Reading(void *lpParam)
{
	char *pBuf;
	int nSize;
	int nLen;
	int nReadLen;
	
	IMSOCKET_TOOLS *pSocket;
	
	pSocket = ( IMSOCKET_TOOLS* )lpParam;
	
	nLen = 0;
	nReadLen = 0;
	nSize = DEFAULT_SEND_BUF_SIZE;
	pBuf = Tools_Malloc(nSize);
	
	while (!pSocket->bStop)
	{
		while (TRUE) {
			//printf("\nread....");
			nReadLen=recv(pSocket->iSocket, pBuf+nLen, 1, 0 );
			//printf("\nread len:%d",nReadLen);
			if (nReadLen==0) {
				printf("\n read data error");
				break;
			}
			printf("%c",pBuf[nLen]);
			if (pBuf[nLen]==0) {
				//printf("\n read data end");
				
				break;
			}
			
			if (nLen>=nSize-2) {
				//空间已经不够,进行扩展
				nSize+=DEFAULT_SEND_BUF_SIZE;
				char *p = Tools_Malloc(nSize);
				memcpy(p, pBuf, nLen+1);
				Tools_Free(&pBuf);
				pBuf = p;
			}
			nLen++;
		}
		//printf("\n*********************************************\nread:%s", pBuf);
		if (nLen<=0) {
			SLEEP(100);
			continue;
		}
		
		printf("\nread msg*****************\n%s",pBuf);
		if(pSocket->pCallBack)
		{
			pSocket->pRecv = pBuf;
			pSocket->pCallBack(pSocket, 0);
		}
		nLen = 0;
		memset(pBuf, 0, nSize);
	}
	return NULL;
}

void ImSocketTools_Send(IMSOCKET_TOOLS *pSocket, char *pBuf, int nLen)
{
	//加锁以便复制临时发送数据
	ImSocketTools_Lock(pSocket);
	
	if (pSocket->nLen+nLen>pSocket->nSize) {
		//扩大缓冲区
		int n = nLen/DEFAULT_SEND_BUF_SIZE;
		n++;
		pSocket->nSize+=(DEFAULT_SEND_BUF_SIZE*n);
		char *p = Tools_Malloc(pSocket->nSize+DEFAULT_SEND_BUF_SIZE);
		memcpy(p, pSocket->pBuf, pSocket->nLen);
		
		Tools_Free(&pSocket->pBuf);
		pSocket->pBuf = p;
	}
	
	//追加新的要发送数据
	if (pSocket->nLen>0) {
		memcpy(pSocket->pBuf+pSocket->nLen, pBuf, nLen);
		pSocket->nLen+=nLen+1;
	}
	else
	{
		memcpy(pSocket->pBuf, pBuf, nLen);
		pSocket->nLen = nLen+1;
	}

	
	//解锁,以便给主线程向等待发送缓冲定入数据
	ImSocketTools_UnLock(pSocket);
}

void* ImSocketTools_Sending(void *lpParam)
{
	char *pSendBuf;
	int nLen;
	int nSize;
	
	IMSOCKET_TOOLS *pSocket;
	
	pSocket = ( IMSOCKET_TOOLS* )lpParam;
	
	nSize = pSocket->nSize;
	pSendBuf = Tools_Malloc(nSize);
	nLen = 0;
	while (!pSocket->bStop) {
		if (pSocket->nLen<=0) {
			//如果要发送的缓冲大小为0,继续等待
			//printf("\n wait send data");
			SLEEP(100);
			continue;
		}
		
		//加锁以便复制临时发送数据
		ImSocketTools_Lock(pSocket);
		//printf("\n send data start 0");
		if (pSocket->nSize>nSize) {
			//
			Tools_Free(&pSendBuf);
			nSize=pSocket->nSize;
			pSendBuf = Tools_Malloc(nSize);
		}
		//复制发送数据
		memcpy(pSendBuf, pSocket->pBuf, pSocket->nLen);
		nLen = pSocket->nLen;
		
		pSocket->nLen = 0;
		memset(pSocket->pBuf, 0, pSocket->nSize);
		
		//解锁,以便给主线程向等待发送缓冲定入数据
		ImSocketTools_UnLock(pSocket);
				
		//发送数据
		if (nLen>0) {
			int nPos = 0;
			char *p = pSendBuf;
			while (p[0]!=0x00) {
				printf("\n send ******************\n%s",p);
				send( pSocket->iSocket, p, strlen(p), 0);
				p = p+strlen(p)+1;
			}
			
		}
		
		memset(pSendBuf, 0, nSize);
				//printf("\n send data end");
	}
	return NULL;
}

TBOOL ImSocketTools_Lock( IMSOCKET_TOOLS *pSocket )
{
	while (pSocket->bLock) {
		SLEEP(10);
	}
	pSocket->bLock = TRUE;
 	return TRUE;
}

TBOOL ImSocketTools_UnLock( IMSOCKET_TOOLS *pSocket )
{
	pSocket->bLock = FALSE;
	return TRUE;
}
